home *** CD-ROM | disk | FTP | other *** search
/ The 640 MEG Shareware Studio 2 / The 640 Meg Shareware Studio CD-ROM Volume II (Data Express)(1993).ISO / clang / tcplusx.zip / KEYBOARD.CPP < prev    next >
C/C++ Source or Header  |  1991-02-28  |  7KB  |  306 lines

  1. //
  2. // keyboard.cpp - implementation for class Keyboard
  3. // Author        - Robin W. McKean
  4. // Last Update    - February 21,1991
  5. // Copyright (C) 1991 All rights reserved
  6. //
  7. // This file remains the property of the author, Robin W. McKean.  You are
  8. // free to use and change it as you see fit.  This module, nor its object
  9. // code, may not however be included  in any packaged software without the
  10. // written consent of the author.
  11. //
  12.  
  13. // Contents ----------------------------------------------------------------
  14. //
  15. //        Keyboard::Keyboard
  16. //        Keyboard::isA
  17. //        Keyboard::nameOf
  18. //        Keyboard::processA
  19. //        Keyboard::pollDevice
  20. //
  21. // Description
  22. //
  23. //      Defines the class Keyboard.  The purpose of this class is to input
  24. //      information from the keyboard, tranlate that into an event and pass
  25. //        it back to the user for processing.
  26. //            
  27. // End ---------------------------------------------------------------------
  28.  
  29. // Interface dependencies --------------------------------------------------
  30.  
  31. #ifndef _IOSTREAM_H
  32. #include <iostream.h>
  33. #endif
  34.  
  35. #ifndef _USETYPES_H
  36. #include <usetypes.h>
  37. #endif
  38.  
  39. #ifndef _GEN_H
  40. #include <gen.h>
  41. #endif
  42.  
  43. #ifndef _EVENT_H
  44. #include <event.h>
  45. #endif
  46.  
  47. #ifndef _KEYBOARD_H
  48. #include <keyboard.h>
  49. #endif
  50.  
  51. // End Interface dependencies ----------------------------------------------
  52.  
  53. // Implementation dependencies ---------------------------------------------
  54.  
  55. #ifndef _DOS_H
  56. #define _DOS_H
  57. #include <dos.h>
  58. #endif
  59.  
  60. #ifndef _CONIO_H
  61. #define _CONIO_H
  62. #include <conio.h>
  63. #endif
  64.  
  65. // End Implementation dependencies -----------------------------------------
  66.  
  67. unsigned readKey( unsigned char enhancedBIOS );
  68.  
  69. // Member Function //
  70.  
  71. Keyboard::Keyboard( int initStatus ) : Device( initStatus )
  72.  
  73. // Summary ------------------------------------------------------------------
  74. //
  75. //        Sets the initial status of the keyboard, and resets the control
  76. //        break function
  77. //
  78. // End ---------------------------------------------------------------------
  79. {
  80.     type = D_KEYBOARD;            // Set the keyboard type
  81.     enhancedBIOS = 0;            // Set default state of enhanced BIOS
  82.  
  83.     REGS regs;                    // Check for enhanced BIOS
  84.  
  85.     regs.h.ah = 5;
  86.     regs.x.cx = 0xffff;
  87.     int86( 0x16, ®s, ®s );
  88.  
  89.     // AL = 0 if enhanced BIOS are present
  90.     if( regs.h.al == 0 )
  91.         enhancedBIOS = 0x10;
  92.     else
  93.         enhancedBIOS = 0;
  94.  
  95.     // Now, lets get the control break status, and reset it with ours
  96.     regs.h.ah = 0x33;
  97.     regs.h.al = 0;
  98.     int86( 0x21, ®s, ®s );
  99.  
  100.     breakStatus = regs.h.dl;                // Save the current break status
  101.  
  102.     // Now disable control break
  103.     regs.h.ah = 0x33;
  104.     regs.h.al = 1;
  105.     regs.h.dl = 0;
  106.     int86( 0x21, ®s, ®s );
  107.  
  108.     altKeyStatus = 0;
  109. }
  110.  
  111. // End Keyboard::Keyboard //
  112.  
  113. // Member Function //
  114.  
  115. #pragma argsused
  116. Keyboard::Keyboard( Keyboard& theDevice )
  117.  
  118. // Description -------------------------------------------------------------
  119. //
  120. //        Copies one Keyboard into another
  121. //
  122. // Parameters
  123. //
  124. //        Device&
  125. //
  126. //        The Keyboard to be copied
  127. //
  128. // End ---------------------------------------------------------------------
  129. {
  130. }
  131.  
  132. // End Keyboard::Keyboard //
  133.  
  134. // Member Function
  135.  
  136. Keyboard::~Keyboard( )
  137. {
  138.     // Reset the control break status
  139.     REGS regs;
  140.  
  141.     regs.h.ah = 0x33;
  142.     regs.h.al = 1;
  143.     regs.h.dl = breakStatus;
  144.     int86( 0x21, ®s, ®s );
  145. }
  146. // Keyboard::~Keyboard //
  147.  
  148. // Member Function //
  149.  
  150. classType Keyboard::isA( ) const
  151.  
  152. // Description -------------------------------------------------------------
  153. //
  154. //        Returns a value representation of a class
  155. //
  156. // End ---------------------------------------------------------------------
  157. {
  158.     return keyboardClass;
  159. }
  160.  
  161. // End Keyboard::isA( ) //
  162.  
  163. // Member Function //
  164.  
  165. char *Keyboard::nameOf( ) const
  166.  
  167. // Description -------------------------------------------------------------
  168. //
  169. //        Returns a character representation of a class
  170. //
  171. // End ---------------------------------------------------------------------
  172. {
  173.     return "Keyboard";
  174. }
  175.  
  176. // End Keyboard::nameOf //
  177.  
  178. // Member Function
  179.  
  180. void Keyboard::pollDevice( )
  181.  
  182. // Description -------------------------------------------------------------
  183. //
  184. //        Reads the keyboard if a keystroke is waiting.  It then builds an
  185. //        event from the keystroke and the key shift state.  If the keyboard
  186. //        status is D_ON, it puts the key into the EventManagers queue.
  187. //
  188. // End ---------------------------------------------------------------------
  189.  
  190. {
  191.     REGS regs;
  192.  
  193.     unsigned int key = 0;
  194.     unsigned int shiftKey;
  195.  
  196.     // Read the current shift state first
  197.     regs.h.ah = 2;
  198.     int86( 0x16, ®s, ®s );
  199.  
  200.     // Shift key status stored in AL
  201.     shiftKey = ( unsigned )regs.h.al;
  202.     int newAltKey = ( int ) shiftKey & K_ALT;
  203.  
  204.     // Check to see if there is a keystroke waiting
  205.     if( !kbhit( ) )
  206.     {
  207.         // No keystroke, now check to see if Alt key status has changed
  208.         if( altKeyStatus && !newAltKey )
  209.         {
  210.             altKeyStatus = 0;            // Alt key was pressed, now released
  211.             key = ALT_KEY_PRESSED;        // Translate into F10
  212.         }
  213.         else
  214.         {
  215.             altKeyStatus = newAltKey;    // Change the alt key status to
  216.             newAltKey = 0;                // current status
  217.         }
  218.     }
  219.  
  220.     // We know there is a key stroke waiting, so fetch it
  221.     else
  222.     {
  223.         key = readKey( enhancedBIOS );
  224.         altKeyStatus = 0;
  225.     }
  226.  
  227.     // If there was something in key, than build an event,
  228.     // but not if the keyboard is disabled
  229.     if( key && status == D_ON )
  230.     {
  231.         Event event;
  232.         event.type = E_KEY;
  233.         event.typeCode = key;
  234.         event.shiftState = shiftKey;
  235.         if( theEventManager ) theEventManager->putEvent( event, FALSE );
  236.     }
  237. }
  238.  
  239. int Keyboard::processA( Event& theEvent )
  240. {
  241.     if( theEvent.type == S_DEVICE && status != D_INACTIVE )
  242.     {
  243.         switch( theEvent.type )
  244.         {
  245.             case D_OFF:
  246.             case D_ON:
  247.                 status = theEvent.type;
  248.                 break;
  249.         }
  250.     }
  251.     return( 0 );
  252. }
  253.  
  254. // This is a function that I use to read the keyboard.    It comes from
  255. // the MicroSoft QuickC compiler, with some few adjustments I have made
  256.  
  257. #pragma argsused
  258. unsigned readKey( unsigned char enhancedBIOS )
  259. {
  260.     unsigned iKey, iShiftstatus;
  261.  
  262.     // Get key code.
  263.     _AH = enhancedBIOS;                 // Non-portable code!
  264.     geninterrupt( 0x16 );
  265.  
  266.     iKey = _AX;                         // Non-portable code!
  267.  
  268.     iShiftstatus = ( unsigned )*( ( unsigned char far * ) 0x417L ) & 0x0f;
  269.  
  270.     // If low byte is not zero, it's an ASCII key. Check scan code to see
  271.     // if it's on the numeric keypad. If not, clear high byte and return.
  272.  
  273.     if( iKey & 0x00ff )
  274.         if( (iKey >> 8) < 69 ) {
  275.         iKey = ( iKey & 0x00ff );
  276.         iShiftstatus &= 0x000f;
  277.         switch( iShiftstatus ) {
  278.             case 4:
  279.             return( 0x0500 | iKey );  // Control ( 5 )
  280.             case 8:
  281.             return( 0x0600 | iKey );  // Alt ( 6 )
  282.             default:
  283.             return( 0x0000 | iKey );
  284.         }
  285.         }
  286.  
  287.     // For function keys and numeric keypad, put scan code in low byte
  288.     // and shift state codes in high byte.
  289.     iKey >>= 8;
  290.     iShiftstatus &= 0x000f;
  291.     switch( iShiftstatus )
  292.     {
  293.     case 0:
  294.         return( 0x0100 | iKey );  // None (1)
  295.     case 1:
  296.     case 2:
  297.     case 3:
  298.         return( 0x0200 | iKey );  // Shift (2)
  299.     case 4:
  300.         return( 0x0300 | iKey );  // Control (3)
  301.     case 8:
  302.         return( 0x0400 | iKey );  // Alt (4)
  303.     }
  304.     return( 0 );
  305. }
  306.